package org.mmtk.plan.metrix;

import org.mmtk.utility.Log;
import org.vmmagic.pragma.Inline;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.ObjectReference;

@Uninterruptible 
public class ClosureCounts { 
	//the number of processors we are simulating
	protected final static int[] procs = {1,2,4,8,16,32,64,128,256,512,1024};
	protected final static int POINTS = procs.length;
	
	//object counters
	private ObjectReference lastPopped;
	protected long popped;
	protected long pushed; 
	protected long iPushed; 
	protected long msPopped;
	protected long msPushed; 
	protected long narrow;
	@Inline
	private void initObjectCounters() {
		this.lastPopped = null;
		this.iPushed = 0;
		this.popped = 0;
		this.pushed = 0;
		this.msPopped = 0;
		this.narrow = 0;
		this.msPushed = 0;
	}
	@Inline
	public void dumpObjectCounters(String message) {
		if (Metrix.PILOT_VERBOSE) {
			Log.write(message);
			Log.write(": Invalid tries to push: ");
			Log.write(this.iPushed);
			/*
			Log.write(": Last popped: ");			
			if(this.lastPopped == null) {
				Log.write(" NOT SET ");
			} else {
				Space space = Space.getSpaceForObject(this.lastPopped);
				if (space == Metrix.myMsSpace) {
					Log.write(" Myms space ");	
				} else if (space == Plan.loSpace) {
					Log.write(" loSpace ");
				} else if (space == Plan.nonMovingSpace) {
					Log.write(" nonMovingSpace ");
				} else if (Plan.USE_CODE_SPACE && space == Plan.smallCodeSpace) {
					Log.write(" smallCodeSpace ");
				} else if (Plan.USE_CODE_SPACE && space == Plan.largeCodeSpace) {
					Log.write(" largeCodeSpace ");
				} else if (space == null) {
				     if (VM.VERIFY_ASSERTIONS) {
				       Log.write("space failure: "); Log.writeln(this.lastPopped);
				     }
				}
			}
			Log.flush();
			VM.objectModel.dumpObject(this.lastPopped);
			Log.flush();
			*/
			Log.write(": Pushed: ");
			Log.write(this.pushed);
			Log.write(" Popped: ");
			Log.write(this.popped);
			Log.write(" MsPushed: ");
			Log.write(this.msPushed);
			Log.write(" MsPopped: ");
			Log.write(this.msPopped);
			Log.write(" Narrow: ");
			Log.writeln(this.narrow);
			Log.flush();
		}
	}
	
	public ClosureCounts() {
		initObjectCounters();
	}
	
	@Inline
	public void init() {
		initObjectCounters();
	}
	
	public void endClosure() {
		//if (Metrix.PILOT_VERBOSE) {
		//	this.dumpObjectCounters();
		//}
	}
	
	public void addPopped(ObjectReference ref) {
		this.popped++;
		this.lastPopped = ref;
	}
	
	public long getMsPushed() {
		return this.msPushed;
	}
	
	public long getPushed() {
		return this.pushed;
	}
	
	public long getIPushed() {
		return this.iPushed;
	}


	public void addMsPushed() {
		this.msPushed++;
	}
	
	public void addPushed() {
		this.pushed++;
	}
	
	public void addIPushed() {
		this.iPushed++;
	}

	public long getMsPopped() {
		return this.msPopped;
	}
	
	public long getPopped() {
		return this.popped;
	}

	/*
	 * Objects is popped from the stack
	 * We need to note how much work is available at the moment
	 */
	public void addMsPopped() {
		this.msPopped++;
	}
	
	public long getNarrow() {
		return this.narrow;
	}

	public void addNarrow() {
		this.narrow++;
	}
	
	public void addDepth(long objects) {
	}
	
	public int getDepth() {
		return 0;
	}
	
	public long getTotalCount() {
		return 0;
	}
	
	public long getMinCount() {
		return 0;
	}
	
	public long getMaxCount() {
		return 0;
	}
}
